package com.java.springcloud.service;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * @Author zhangtao
 * @create 2022/3/8 17:56
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class RedisDistributeLock {

    @Autowired
    private RedissonClient redissonClient;

    public <T> T lock(String key, int waitTime, int leaseTime, Supplier<T> success, Supplier<T> fail) throws Exception {
        RLock lock = redissonClient.getLock(key);
        boolean b = lock.tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS);
        try {
            if (b) {
                return success.get();
            } else {
                return fail.get();
            }
        } finally {
            if (b) {
                if (lock.isLocked()) {
                    lock.unlock();
                }
            }
        }
    }

    public void lock(String key, int waitTime, int leaseTime, Runnable runnable) {
        RLock lock = redissonClient.getLock(key);
        boolean b = false;
        try {
            b = lock.tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS);
            if (b) {
                runnable.run();
            }
        } catch (InterruptedException e) {
            log.error(e.getMessage());
            Thread.currentThread().interrupt();
        } finally {
            if (b) {
                if (lock.isLocked()) {
                    lock.unlock();
                }
            }
        }
    }
}
